﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using MReviewerClient.Providers;
using System.ComponentModel;
using MReviewerClient.MReviewerSvc;
using System.ServiceModel;
using System.Threading;

namespace MReviewerClient.Views
{
    public partial class Configuration : PhoneApplicationPage
    {
        #region Fields

        /// <summary>
        /// Show loading splash progress bar on a separate thread
        /// </summary>
        private BackgroundWorker backroungWorker;

        /// <summary>
        /// Refer to the SvcMReviewerClient
        /// </summary>
        private SvcMReviewerClient SvcMReviewerClientReference = null;

        #endregion

        #region Constructor

        /// <summary>
        /// The default constructor
        /// </summary>
        public Configuration()
        {
            InitializeComponent();
            this.progressBar1.IsIndeterminate = true;
            // Hide the splash progress bar
            this.progressBar1.Visibility = System.Windows.Visibility.Collapsed;
            this.txtLoading.Visibility = System.Windows.Visibility.Collapsed;
        }

        #endregion

        #region Methods & Fields

        /// <summary>
        /// Try to connect to the service with the user input information
        /// </summary>
        private void TryConnectToService()
        {
            backroungWorker = new BackgroundWorker();
            backroungWorker.DoWork += new DoWorkEventHandler(backroungWorker_DoWork);
            backroungWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backroungWorker_RunWorkerCompleted);
            backroungWorker.RunWorkerAsync();
        }

        /// <summary>
        /// Handle worker executing
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void backroungWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            // Display the splash progress bar
            this.Dispatcher.BeginInvoke(() =>
            {
                string ENDPOINT_ADDRESS_NAME = "BasicHttpBinding_ISvcMReviewer";
                string DEFAULT_ENDPOINT_ADDRESS = "http://localhost:18659/SvcMReviewer.svc";

                var serviceURL = string.Format("http://{0}:{1}/{2}", txtServiceName.Text, txtPort.Text, ServiceInfoProvider.SERVICE_PATH);
  
                try
                {
                    // Update service information
                    this.SvcMReviewerClientReference = new MReviewerSvc.SvcMReviewerClient(ENDPOINT_ADDRESS_NAME,
                                    new EndpointAddress(serviceURL == string.Empty ? DEFAULT_ENDPOINT_ADDRESS : serviceURL));
                }
                catch
                {
                    this.SvcMReviewerClientReference = null;
                }
            });
            Thread.Sleep(3000);
        }

        /// <summary>
        /// Handle worker execute completely
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void backroungWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            // Hide the splash progress bar
            this.Dispatcher.BeginInvoke(() =>
            {
                // Show the connection status
                if (this.SvcMReviewerClientReference == null)
                {
                    MessageBox.Show("Cannot connect to the service, please input information and try again", "Information", MessageBoxButton.OK);
                }
                else
                {
                    // Connect successfully
                    var errTxt = ServiceInfoProvider.Instance.StoreServiceInfo(txtServiceName.Text, txtPort.Text);
                    if (errTxt.Equals(string.Empty))
                        MessageBox.Show("The service configuration has been saved", "Information", MessageBoxButton.OK);
                    else
                        MessageBox.Show(errTxt, "Error", MessageBoxButton.OK);
                }

                backroungWorker.DoWork -= new DoWorkEventHandler(backroungWorker_DoWork);
                backroungWorker.RunWorkerCompleted -= new RunWorkerCompletedEventHandler(backroungWorker_RunWorkerCompleted);

                this.progressBar1.Visibility = System.Windows.Visibility.Collapsed;
                this.txtLoading.Visibility = System.Windows.Visibility.Collapsed;
            });
        }

        /// <summary>
        /// Input validation
        /// </summary>
        /// <param name="errTxt"></param>
        /// <returns></returns>
        private bool ValidateUserInput(ref string errTxt)
        {
            // Service Name
            if (txtServiceName.Text.Equals(string.Empty))
            {
                errTxt = "Please input the name of service will be hosted";
                return false;
            }
            // Port
            if (txtPort.Text.Equals(string.Empty))
            {
                errTxt = "Please input the port which is corresponding with service";
                return false;
            }
            return true;
        }

        /// <summary>
        /// The method for saving the information to connect to service
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ApplicationBarIconButtonSave_Click(object sender, EventArgs e)
        {
            var errTxt = string.Empty;

            if (this.ValidateUserInput(ref errTxt))
            {
                if (errTxt.Equals(string.Empty))
                {
                    this.progressBar1.Visibility = System.Windows.Visibility.Visible;
                    this.txtLoading.Visibility = System.Windows.Visibility.Visible;
                    this.TryConnectToService();
                    return;
                }
            }

            MessageBox.Show(errTxt, "Error", MessageBoxButton.OK);
        }

        private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
        {
            this.txtServiceName.Text = ServiceInfoProvider.Instance.ServiceName == null ? string.Empty : ServiceInfoProvider.Instance.ServiceName;
            this.txtPort.Text = ServiceInfoProvider.Instance.Port == null ? string.Empty : ServiceInfoProvider.Instance.Port;
        }

        #endregion
    }
}